/**
 *
 * Copyright (C) 2011 by lunereaper <![[dawid.kraczkowski[at]gmail[dot]com]]>
 * Thanks for Hardy Keppler<![[Keppler.H[at]online.de]]> for shortened version 
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 **/
var JS = {
    VERSION: '2.3.0'
};

/**
 * JS.Class base library
 * easly create and extend your JS.Classes
 * @sample
 * Simple class & object
 * <code>
 * var TestClass = JS.Class(<class definition>);
 * <class definition> is an object with class properties & methods
 * var testObject = new TestClass();
 * </code>
 * Constructor sample
 * <code>
 * var ConstructedClass = JS.Class({
 * 	construct : function(param) {
 * 		this.a = param;
 *  }
 * });
 * var t = new ConstructedClass(12);
 * t.a; // this will return 12
 * </code>
 * 
 * Class static
 * <code>
 * var ClassStatics = JS.Class({
 * 	statics: {
 * 		TEST = 'cst.TEST';
 *  },
 *  a : function() {
 *  	ClassStatics.TEST;//return 'cst.TEST'
 *  	this.TEST;//return undefined
 *  }
 * });
 * ClassStatics.TEST;//return 'cst.TEST'
 * </code>
 * 
 * Extending class
 * <code>
 * var ExtendedClass = TestClass.extend(<class definition>);
 * var extObject = new ExtendedClass();
 * extObject instanceof ExtendedClass; //return true
 * extObject instanceof TestClass; //return true
 * </code>
 * 
 * Calling parent overriden method
 * <code>
 * 
 * </code>
 * 
 * @version 2.3.0
 * 
 */
JS.Class = function (classBody) {

	var preventContructorCall = false;
	
	return (function createClass(self, classBody) {
		
		var classConstructor = function () {
			//apply constructor pattern
			if (typeof this['construct'] === 'function' && preventContructorCall === false) {
				this.construct.apply(this, arguments);
			}
		};
		
		//make new class instance of extended object
		if (self !== null) {
			preventContructorCall = true;
			classConstructor.prototype = new self();
			preventContructorCall = false;
		}
		
		var classPrototype = classConstructor.prototype;
		
		//create class body
		for (var prop in classBody) {
			if (prop === 'statics') {//rewrite statics
				for (var sProp in classBody.statics) {
					classPrototype[sProp] = classBody.statics[sProp];
				}
				continue;
			}
			
			//provide parent calls if method is overriden
			if (typeof classPrototype === 'function') {
				classPrototype['parent'] = classPrototype['parent'] || {};
				classPrototype.parent[prop] = classPrototype[prop];
			}
			
			//rewrite property
			classPrototype[prop] = classBody[prop];
		}
		
		//provide extending option in JS.Class
		classConstructor.extend = function (classBody) {
			return createClass(this, classBody);
		};
		
		return classConstructor;
	})(null, classBody);
};